using System;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using Newtonsoft.Json;

namespace MqttPublisher
{
    public class MqttService
    {
        private IMqttClient _mqttClient;
        private MqttClientOptions _options;
        private bool _isConnected = false;

        public IMqttClient MqttClient => _mqttClient;

        public event EventHandler<string> OnStatusChanged;
        public event EventHandler<string> OnMessageSent;

        public bool IsConnected => _isConnected;

        public async Task<bool> ConnectAsync(string brokerIp = "127.0.0.1", int port = 1883, string username = null, string password = null)
        {
            try
            {
                var factory = new MqttFactory();
                _mqttClient = factory.CreateMqttClient();

                var optionsBuilder = new MqttClientOptionsBuilder()
                    .WithTcpServer(brokerIp, port)
                    .WithClientId(Guid.NewGuid().ToString())
                    .WithCleanSession();

                if (!string.IsNullOrEmpty(username))
                {
                    optionsBuilder.WithCredentials(username, password);
                }

                _options = optionsBuilder.Build();

                _mqttClient.ConnectedAsync += OnConnectedAsync;
                _mqttClient.DisconnectedAsync += OnDisconnectedAsync;

                var result = await _mqttClient.ConnectAsync(_options);
                
                if (result.ResultCode == MqttClientConnectResultCode.Success)
                {
                    _isConnected = true;
                    OnStatusChanged?.Invoke(this, "已连接到MQTT Broker");
                    return true;
                }
                else
                {
                    OnStatusChanged?.Invoke(this, $"连接失败: {result.ResultCode}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                OnStatusChanged?.Invoke(this, $"连接异常: {ex.Message}");
                return false;
            }
        }

        public async Task DisconnectAsync()
        {
            try
            {
                if (_mqttClient != null && _isConnected)
                {
                    await _mqttClient.DisconnectAsync();
                    _isConnected = false;
                    OnStatusChanged?.Invoke(this, "已断开连接");
                }
            }
            catch (Exception ex)
            {
                OnStatusChanged?.Invoke(this, $"断开连接异常: {ex.Message}");
            }
        }

        public async Task<bool> PublishJsonAsync(string topic, object data)
        {
            if (!_isConnected || _mqttClient == null)
            {
                OnStatusChanged?.Invoke(this, "未连接到MQTT Broker");
                return false;
            }

            try
            {
                string jsonPayload = JsonConvert.SerializeObject(data, Formatting.Indented);
                
                var message = new MqttApplicationMessageBuilder()
                    .WithTopic(topic)
                    .WithPayload(Encoding.UTF8.GetBytes(jsonPayload))
                    .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
                    .WithRetainFlag(false)
                    .Build();

                var result = await _mqttClient.PublishAsync(message);
                
                if (result.IsSuccess)
                {
                    OnMessageSent?.Invoke(this, $"消息已发送到主题 '{topic}': {jsonPayload}");
                    return true;
                }
                else
                {
                    OnStatusChanged?.Invoke(this, $"发送失败: {result.ReasonString}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                OnStatusChanged?.Invoke(this, $"发送异常: {ex.Message}");
                return false;
            }
        }

        private Task OnConnectedAsync(MqttClientConnectedEventArgs arg)
        {
            _isConnected = true;
            OnStatusChanged?.Invoke(this, "MQTT客户端已连接");
            return Task.CompletedTask;
        }

        private Task OnDisconnectedAsync(MqttClientDisconnectedEventArgs arg)
        {
            _isConnected = false;
            OnStatusChanged?.Invoke(this, $"MQTT客户端已断开: {arg.Reason}");
            return Task.CompletedTask;
        }

        public static string GenerateTransactionId()
        {
            var now = DateTime.Now;
            var dateTime = now.ToString("yyyyMMddHHmmssfff");
            var random = new Random().Next(1000, 9999);
            return $"{dateTime}{random}";
        }

        public static string BuildDeviceTopic(DeviceType deviceType)
        {
            return $"/{deviceType}/sensor/data";
        }

        public void Dispose()
        {
            _mqttClient?.Dispose();
        }
    }

    // 示例数据模型
    public class PlantIoData
    {
        public DateTime Timestamp { get; set; }
        public string DeviceId { get; set; }
        public double Temperature { get; set; }
        public double Humidity { get; set; }
        public bool Status { get; set; }
        public string Message { get; set; }
    }

    // 设备状态请求数据模型
    public class EquipmentStateRequest
    {
        public string messageName { get; set; } = "eqpStateRequest";
        public string deviceCode { get; set; }
        public string equipmentName { get; set; }
        public string transactionID { get; set; }
        public string timeStamp { get; set; }
        public EquipmentParameters parameters { get; set; }
    }

    public class EquipmentParameters
    {
        public int onlineState { get; set; }
        public int deviceStatus { get; set; }
        public int deviceStatusType { get; set; }
        public int safeState { get; set; }
        public int colorLightState { get; set; }
        public int operationMode { get; set; }
    }

    // Topic类型枚举
    public enum DeviceType
    {
        mirror,
        fac,
        fl,
        sac
    }
}